package com.company.cloud.page.modules.mgr.service.impl;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.sql.ast.expr.SQLCaseExpr;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.company.cloud.common.asserts.ValidatorUtils;
import com.company.cloud.common.bean.DataMapEntity;
import com.company.cloud.common.bean.LoginSimpleUserInfo;
import com.company.cloud.common.constant.BaseConstant;
import com.company.cloud.common.constant.BaseReturnEnum;
import com.company.cloud.common.exception.BusinessException;
import com.company.cloud.common.utils.CheckUtils;
import com.company.cloud.common.utils.ConvertByTypeUtils;
import com.company.cloud.page.constant.PageDataTypeEnum;
import com.company.cloud.page.modules.base.entity.PageCardConfigInfo;
import com.company.cloud.page.modules.base.entity.PageComponentConfig;
import com.company.cloud.page.modules.base.entity.PageComponentInfo;
import com.company.cloud.page.modules.base.entity.PageInfo;
import com.company.cloud.page.modules.base.service.PageComponentConfigService;
import com.company.cloud.page.modules.base.service.PageComponentInfoService;
import com.company.cloud.page.modules.base.service.PageInfoService;
import com.company.cloud.page.modules.cache.models.PageCardModel;
import com.company.cloud.page.modules.cache.models.WebPageComponentModel;
import com.company.cloud.page.modules.cache.models.WebPageConfigModel;
import com.company.cloud.page.modules.cache.utils.PageConvertUtils;
import com.company.cloud.page.modules.cache.utils.WebPageConvertUtils;
import com.company.cloud.page.modules.kit.TemplateKit;
import com.company.cloud.page.modules.mgr.controller.req.WebPageComponentUpdateParam;
import com.company.cloud.page.modules.mgr.controller.req.WebPageConfigAdd2EditParam;
import com.company.cloud.page.modules.mgr.controller.req.WebPageConfigQuery4PageParam;
import com.company.cloud.page.modules.mgr.controller.req.WebPageConfigUpDownParam;
import com.company.cloud.page.modules.mgr.service.WebPageConfigMgrService;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.NativeWebRequest;

import java.security.Key;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;

@Service
public class WebPageConfigMgrServiceImpl implements WebPageConfigMgrService {

    @Autowired
    private PageComponentInfoService pageComponentInfoService;
    @Autowired
    private PageInfoService pageInfoService;
    @Autowired
    private PageComponentConfigService pageComponentConfigService;


    //-----------------------------------------------------------------------

    @Override
    public IPage<WebPageConfigModel> query(WebPageConfigQuery4PageParam params, LoginSimpleUserInfo userInfo) {
        IPage<PageInfo> page = pageInfoService.page(
                new Page<PageInfo>(params.getPage(), params.getRows()),
                new QueryWrapper<PageInfo>()
                    .eq("rows_state",BaseConstant.EnabledEnum.ENABLED.getCode())
                    .eq(StrUtil.isNotEmpty(params.getPageNo()),"page_no",params.getPageNo())
                    .eq(StrUtil.isNotEmpty(params.getState()),"state",params.getState())
                    .like(StrUtil.isNotEmpty(params.getPageName()),"page_name",params.getPageName())
                );

        IPage<WebPageConfigModel> data = page.convert(new Function<PageInfo, WebPageConfigModel>() {
            @Override
            public WebPageConfigModel apply(PageInfo entity) {
                return WebPageConvertUtils.getWebPageConfigNotContent(entity);
            }
        });
        return data;
    }

    @Transactional
    @Override
    public void save(WebPageConfigAdd2EditParam params, LoginSimpleUserInfo userInfo) {
        ValidatorUtils.validate(params);
        if(CheckUtils.isEmpty(params.getPageContent())){
           throw new BusinessException(BaseReturnEnum.PARAM_NULL);
        }

        Dict dict= this.temp2component(params.getPageNo(), params.getPageContent(), new HashSet<String>(),userInfo);
        String pageContent= dict.getStr("temp");
        List<PageComponentInfo> componentEntityList =dict.get("componentList",new ArrayList<PageComponentInfo>());

        PageInfo entity=new PageInfo();
        entity.setPageNo(params.getPageNo());
        entity.setPageName(params.getPageName());
        entity.setPageContent(pageContent);
        entity.setShareStyle(params.getShareStyle());
        entity.setShareTitle(params.getShareTitle());
        entity.setShareMemo(params.getShareMemo());
        entity.setShareImg(params.getShareImg());
        entity.setMetaKeywords(params.getMetaKeywords());
        entity.setMetaDescription(params.getMetaDescription());
        entity.setState(params.getState());
        entity.addCreateParam(userInfo);
        entity.addEditParam(userInfo);
        pageInfoService.save(entity);

        if(componentEntityList.size()>0){
            pageComponentInfoService.saveBatch(componentEntityList);
        }
    }

    //模板和组件
    private Dict temp2component(String pageNo, String content,Set<String> pageComponentNoList, LoginSimpleUserInfo userInfo){
        Dict data=Dict.create();
        data.put("temp",content);

        List<PageComponentInfo> componentList=new ArrayList<>();
        Map<String,String> pageComponentMap= TemplateKit.getPageTempParse(content);

        Map<String,PageComponentConfig> pageComponentConfigMap=new HashMap<>();

        if(!CollectionUtils.isEmpty(pageComponentMap)){

            Set<String> cfSet=new HashSet<>();
            for(String key:pageComponentMap.keySet()){
                if(pageComponentNoList.contains(key)){
                    cfSet.add(key);
                }
            }

            cfSet.forEach(key ->{
                pageComponentMap.remove(key);
                pageComponentNoList.remove(key);
            });

            System.out.println("+++++ 重复 size  ="+ cfSet.size());
            System.out.println("+++++ 新增 size  ="+ pageComponentMap.keySet().size());
            System.out.println("+++++ 移除 size  ="+ pageComponentNoList.size());

            if(pageComponentMap.keySet().size()>0){
                List<PageComponentConfig> pageComponentConfigList = pageComponentConfigService.list(new QueryWrapper<PageComponentConfig>()
                        .eq("rows_state", BaseConstant.EnabledEnum.ENABLED.getCode())
                        .in("code",pageComponentMap.values())
                );
                if(!CollectionUtils.isEmpty(pageComponentConfigList)){
                    pageComponentConfigList.forEach(item->{
                        pageComponentConfigMap.put(item.getCode(),item);
                    });
                }
            }

        }

        pageComponentMap.forEach((k,v)->{
            PageComponentConfig pcc = pageComponentConfigMap.get(v);
            if(pcc!=null){
                PageComponentInfo entity=new PageComponentInfo();
                entity.setPageComponentNo(k);
                entity.setPageNo(pageNo);
                entity.setComponentNo(v);
                entity.setDataType(pcc.getDataType());
                entity.setData(pcc.getData());
                entity.setDs(pcc.getDs());
                entity.setDsAttributeRel(pcc.getDsAttributeRel());
                entity.setOrders(1);
                entity.addCreateParam(userInfo);
                entity.addEditParam(userInfo);
                componentList.add(entity);
            }
        });

        data.put("componentList",componentList);

        data.put("removeComponentList",pageComponentNoList);

        return data;
    }

    @Override
    public void update(WebPageConfigAdd2EditParam params, LoginSimpleUserInfo userInfo) {
        ValidatorUtils.validate(params);
        PageInfo entity=pageInfoService.getById(params.getPageNo());
        if(entity==null || BaseConstant.EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())){
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }


        List<PageComponentInfo> pageComponentList = pageComponentInfoService.list(new QueryWrapper<PageComponentInfo>()
                .eq("page_no",params.getPageNo())
                .eq("rows_state", BaseConstant.EnabledEnum.ENABLED.getCode())
        );

        Set<String> pageComponentNoList=new HashSet<>();
        if(!CollectionUtils.isEmpty(pageComponentList)){
            pageComponentList.forEach(item->{
                pageComponentNoList.add(item.getPageComponentNo());
            });
        }

        Dict dict= this.temp2component(params.getPageNo(), params.getPageContent(),pageComponentNoList,userInfo);
        String pageContent= dict.getStr("temp");
        List<PageComponentInfo> componentEntityList =dict.get("componentList",new ArrayList<PageComponentInfo>());
        Set<String> removeComponentList=dict.get("removeComponentList",new HashSet<String>());

        entity.setPageName(params.getPageName());
        entity.setShareStyle(params.getShareStyle());
        entity.setShareTitle(params.getShareTitle());
        entity.setShareMemo(params.getShareMemo());
        entity.setShareImg(params.getShareImg());
        entity.setPageContent(pageContent);
        entity.setMetaKeywords(params.getMetaKeywords());
        entity.setMetaDescription(params.getMetaDescription());
        entity.addEditParam(userInfo);
        pageInfoService.updateById(entity);

        if(componentEntityList.size()>0){
            pageComponentInfoService.saveBatch(componentEntityList);
        }

        if(removeComponentList.size()>0){
            pageComponentInfoService.removeByIds(removeComponentList);
        }

    }

    @Override
    public void del(String pageNo, LoginSimpleUserInfo userInfo) {
        PageInfo entity=pageInfoService.getById(pageNo);
        if(entity==null || BaseConstant.EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())){
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        entity.setRowsState(BaseConstant.EnabledEnum.DISABLED.getCode());
        entity.addEditParam(userInfo);
        pageInfoService.updateById(entity);
    }

    @Override
    public WebPageConfigModel info(String pageNo) {
        PageInfo entity=pageInfoService.getById(pageNo);
        if(entity==null || BaseConstant.EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())){
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        List<PageComponentInfo> pageComponentList = pageComponentInfoService.list(new QueryWrapper<PageComponentInfo>()
                .eq("page_no",entity.getPageNo())
                .eq("rows_state",BaseConstant.EnabledEnum.ENABLED.getCode())
                .orderByAsc("orders")
        );
        return WebPageConvertUtils.getWebPageConfig(entity);
    }

    @Override
    public void updown(WebPageConfigUpDownParam params, LoginSimpleUserInfo userInfo) {
        ValidatorUtils.validate(params);
        PageInfo entity=pageInfoService.getById(params.getPageNo());
        if(entity==null || BaseConstant.EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())){
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        if(entity.getState().equals(params.getState())){
            return ;
        }
        entity.setState(params.getState());
        entity.addEditParam(userInfo);
        pageInfoService.updateById(entity);

    }


    //-----------------------------------------------------------------------
    @Override
    public WebPageComponentModel pageComponentUpdate(WebPageComponentUpdateParam params, LoginSimpleUserInfo userInfo) {
        ValidatorUtils.validate(params);
        PageComponentInfo entity= pageComponentInfoService.getById(params.getPageComponentNo());
        if(entity==null || BaseConstant.EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())){
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        entity.setDataType(params.getDataType());

        if(StrUtil.isNotEmpty(params.getDataType())){
            if(PageDataTypeEnum.PDT_Obj.getCode().equals(params.getDataType())){
                if(params.getData()!=null){
                    entity.setData(JSON.toJSONString(params.getData()));
                }
            }
            if(PageDataTypeEnum.PDT_List.getCode().equals(params.getDataType())){
                if(!CollectionUtils.isEmpty(params.getDataList())){
                    entity.setData(JSON.toJSONString(params.getDataList()));
                }
            }
        }

        if(params.getDs()!=null){
            entity.setDs(JSON.toJSONString(params.getDs()));
        }

        if(params.getDsAttributeRel()!=null){
            entity.setDsAttributeRel(JSON.toJSONString(params.getDsAttributeRel()));
        }
        entity.addEditParam(userInfo);
        pageComponentInfoService.updateById(entity);
        PageComponentConfig configEntity= pageComponentConfigService.getById(entity.getComponentNo());
        return WebPageConvertUtils.getWebPageComponent(entity,configEntity);
    }

    @Override
    public WebPageComponentModel pageComponentInfo(String pageComponentNo) {
        PageComponentInfo entity= pageComponentInfoService.getById(pageComponentNo);
        if(entity==null || BaseConstant.EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())){
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        PageComponentConfig configEntity= pageComponentConfigService.getById(entity.getComponentNo());
        return WebPageConvertUtils.getWebPageComponent(entity,configEntity);
    }

    @Override
    public void pageComponentDel(String pageComponentNo, LoginSimpleUserInfo userInfo) {
        PageComponentInfo entity= pageComponentInfoService.getById(pageComponentNo);
        if(entity==null || BaseConstant.EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())){
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }
        entity.setRowsState(BaseConstant.EnabledEnum.DISABLED.getCode());
        entity.addEditParam(userInfo);
        pageComponentInfoService.updateById(entity);


        PageInfo pageInfo= pageInfoService.getById(entity.getPageNo());
        if(pageInfo==null || BaseConstant.EnabledEnum.DISABLED.getCode().equals(pageInfo.getRowsState())){
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }

        String newContent= TemplateKit.removePageComponentTemp(pageInfo.getPageContent(),pageComponentNo);

        if(StrUtil.isNotEmpty(newContent)){
            pageInfo.setPageContent(newContent);
            pageInfo.addEditParam(userInfo);
            pageInfoService.updateById(pageInfo);
        }
    }

    //-----------------------------------------------------------------------


    public WebPageConfigModel info2(String pageNo) {
        PageInfo entity=pageInfoService.getById(pageNo);
        if(entity==null || BaseConstant.EnabledEnum.DISABLED.getCode().equals(entity.getRowsState())){
            throw new BusinessException(BaseReturnEnum.DATA_NOT_EXISTS);
        }

        //
        List<PageComponentInfo> pageComponentList = pageComponentInfoService.list(new QueryWrapper<PageComponentInfo>()
                .eq("page_no",entity.getPageNo())
                .eq("rows_state",BaseConstant.EnabledEnum.ENABLED.getCode())
        );

        //
        Map<String,PageComponentConfig> pageComponentConfigMap=new HashMap<>();
        Set<String> componentConfigNos=new HashSet<>();
        if(!CollectionUtils.isEmpty(pageComponentList)){
            pageComponentList.forEach(item->{
                componentConfigNos.add(item.getComponentNo());
            });
        }
        if(componentConfigNos.size()>0){
            List<PageComponentConfig> pageComponentConfigList = pageComponentConfigService.listByIds(componentConfigNos);
            if(!CollectionUtils.isEmpty(pageComponentConfigList)){
                pageComponentConfigList.forEach(item->{
                    pageComponentConfigMap.put(item.getCode(),item);
                });
            }
        }

        //
        return WebPageConvertUtils.getWebPageConfig(entity,pageComponentList,pageComponentConfigMap);
    }


    @Override
    public String getPageContent(String pageNo, boolean isDev) {
        WebPageConfigModel  entity= this.info2(pageNo);
        Map<String,Object> pageData=new HashMap<>();
        pageData.put("metaKeywords",entity.getMetaKeywords());
        pageData.put("metaDescription",entity.getMetaDescription());

        Set<String> cssUrls=new HashSet<>();
        Set<String> jsUrls=new HashSet<>();

        if(isDev){
            cssUrls.add("https://www.artshanghaifair.com/js/editor.css");
            jsUrls.add("https://www.artshanghaifair.com/js/editor.js");
        }

        List<WebPageComponentModel> componentList = entity.getComponentList();
        if(!CollectionUtils.isEmpty(componentList)){
            componentList.forEach(component->{

                if(StrUtil.isNotEmpty(component.getDataType())){
                    if(PageDataTypeEnum.PDT_Obj.getCode().equals(component.getDataType())){
                        String componentContent= TemplateKit.getContent(component.getContent(),component.getData());
                        System.out.println(StrUtil.format("+++++(对象)组件编号:{},组件内容:{}",component.getPageComponentNo(),componentContent));

                        String _pageComponentNo=component.getPageComponentNo().trim();
                        if(isDev){

                            pageData.put(_pageComponentNo, TemplateKit.getDevPageComponentTemp(componentContent,_pageComponentNo));
                        }else{
                            pageData.put(_pageComponentNo,componentContent);
                        }

                    }

                    if(PageDataTypeEnum.PDT_List.getCode().equals(component.getDataType())){
                        Map<String,Object> pageParasMap=new HashMap<>();
                        if(!CollectionUtils.isEmpty(component.getDataList())){
                            pageParasMap.put("list",component.getDataList());
                        }
                        String componentContent= TemplateKit.getContent(component.getContent(),pageParasMap);
                        System.out.println(StrUtil.format("+++++(列表)组件编号:{},组件内容:{}",component.getPageComponentNo(),componentContent));
                        String _pageComponentNo=component.getPageComponentNo().trim();
                        if(isDev){
                            pageData.put(_pageComponentNo, TemplateKit.getDevPageComponentTemp(componentContent,_pageComponentNo));
                        }else{
                            pageData.put(_pageComponentNo,componentContent);
                        }

                    }
                }
                if(!CollectionUtils.isEmpty(component.getJsUrls())){
                    jsUrls.addAll(component.getJsUrls());
                }
                if(!CollectionUtils.isEmpty(component.getCssUrls())){
                    cssUrls.addAll(component.getCssUrls());
                }
            });
        }

        if(cssUrls.size()>0){
            pageData.put("cssUrls",cssUrls);
        }
        if(jsUrls.size()>0){
            pageData.put("jsUrls",jsUrls);
        }



        return TemplateKit.getContent(entity.getPageContent(),pageData);
    }


}
